﻿using System.Data;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace 数学口算题
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btn_Make_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                txt_Result.Text = "";
                txt_eResult.Text = "";
                int QuestionNumber = 0;
                try { QuestionNumber = Convert.ToInt32(txt_QuestionNum.Text); } catch { }
                for (int i = 0; i < QuestionNumber; i++)
                {
                    string Question = MakeQuestion();
                    string? r = (new DataTable()).Compute(Question.Replace("=", ""),"1=1")?.ToString();
                    if (!string.IsNullOrEmpty(txt_Result.Text))
                        txt_Result.Text += System.Environment.NewLine;
                    if (!string.IsNullOrEmpty(txt_eResult.Text))
                        txt_eResult.Text += System.Environment.NewLine;
                    txt_Result.Text += Question;
                    txt_eResult.Text += r;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ":" + ex.StackTrace);
            }
        }

        private Random rnd = new Random();
        private string MakeQuestion()
        {
            string Question = "";
            try
            {
                Func<string> GetMethod = () => {
                    string m = "+";
                    decimal rate = 0; try { decimal.TryParse(txt_minorschance.Text, out rate); } catch { }
                    //decimal v = rate / 100m;
                    //int value = 9 - ((int)(9m * v) + 1);
                    //if (value < 0)
                    //    value = 0;
                    //if (rnd.Next(9) > value)
                    //    m = "-";
                    if (rate > 99)
                        rate = 99;
                    if (rate < 1)
                        rate = 0;
                    if (rnd.Next(99) > (99 - ((int)rate)))
                        m = "-";
                    return m;
                };
                string method = GetMethod();

                /*
                 * forceState:
                 * 1:强制个位
                 * 2:强制2位数
                 * 3:强制避免个位
                 * 4:强制避免2位
                 */
                Func<int, int, int> GetDigit = (max, forceState) => {
                    int number = 0;
                    int min = 1;
                    if (forceState != 3 && (chk_lessThan20?.IsChecked ?? false || forceState == 1))
                    {
                        int mmax = max;
                        if (mmax == 0)
                        {
                            mmax = 9;
                            min = 3;
                        }
                        if (mmax == 1)
                        {
                            min = 0;
                        }
                        if (mmax > 9)
                            mmax = 9;
                        number = rnd.Next(min, mmax);
                    }
                    if (forceState != 4 && (rnd.Next(99) > 50 && (chk_2digit?.IsChecked ?? false) || forceState == 2))
                    {
                        int mmax = max;
                        if (mmax == 0)
                        {
                            mmax = 99;
                            min = 3;
                        }
                        min = 10;
                        if (min > mmax)
                            min = mmax - 1;

                        number = rnd.Next(min, mmax);
                    }
                    return number;
                };
                int forceState = 0;
                int FirstNum = GetDigit(0, forceState);
                int SecondNum = GetDigit(0, forceState);
                int FirstSectionTotal = 0;
                int Rate = Convert.ToInt32(chk_mustimprove.Text);
                switch (method)
                {
                    case "+":
                        SecondNum = GetDigit(0, forceState);
                        FirstSectionTotal = FirstNum + SecondNum;
                        {
                            int firstl = Convert.ToInt32(FirstNum.ToString().Substring(FirstNum.ToString().Length - 1, 1));
                            int secondl = Convert.ToInt32(SecondNum.ToString().Substring(SecondNum.ToString().Length - 1, 1));
                            int mindiff = 10 - firstl - secondl;
                            if (mindiff > 0 && mindiff < 9 && rnd.Next(0, 99) < Rate)
                            {
                                int rand = rnd.Next((mindiff + 1), 9);
                                SecondNum += rand;
                                FirstSectionTotal = FirstNum + SecondNum;
                            }
                        }
                        break;
                    default:
                        FirstNum = GetDigit(0, 2);
                        SecondNum = GetDigit(FirstNum, forceState);
                        FirstSectionTotal = FirstNum - SecondNum;
                        {
                            int firstl = Convert.ToInt32(FirstNum.ToString().Substring(FirstNum.ToString().Length - 1, 1));
                            int secondl = Convert.ToInt32(SecondNum.ToString().Substring(SecondNum.ToString().Length - 1, 1));
                            int mindiff = firstl - secondl;
                            if (mindiff > 0 && mindiff < 9 && rnd.Next(0, 99) < Rate)
                            {
                                int rand = rnd.Next((mindiff + 1), 9);
                                SecondNum += rand;
                                if (FirstNum < 90 && ((FirstNum - SecondNum) < 0))
                                    FirstNum += 10;
                                else if ((FirstNum - SecondNum) < 0)
                                    SecondNum -= 10;
                                FirstSectionTotal = FirstNum - SecondNum;
                            }
                        }
                        break;
                }

                string Multi = "";
                int NormalThirdChance = rnd.Next(99);
                int QuotePoints = rnd.Next(99);
                int QuoteChance = 0;
                try {
                    int.TryParse(txt_quotechance.Text, out QuoteChance);
                } catch { }
                if ((NormalThirdChance > 50) || (QuotePoints < QuoteChance) )
                {
                    string nextMethod = "";
                    if (chk_multiSame?.IsChecked ?? false)
                    {
                        nextMethod = method;
                    }
                    if (rnd.Next(99) > 50)
                    {
                        nextMethod = GetMethod();
                    }
                    int ThirdNum = 0;

                    if (QuotePoints < QuoteChance)
                    {
                        switch (nextMethod)
                        {
                            case "+":
                                ThirdNum = GetDigit(0, forceState);
                                {
                                    int firstl = Convert.ToInt32(FirstSectionTotal.ToString().Substring(FirstSectionTotal.ToString().Length - 1, 1));
                                    int secondl = Convert.ToInt32(ThirdNum.ToString().Substring(ThirdNum.ToString().Length - 1, 1));
                                    int mindiff = 10 - firstl - secondl;
                                    if (mindiff > 0 && mindiff < 9 && rnd.Next(0, 99) < Rate)
                                    {
                                        int rand = rnd.Next((mindiff + 1), 9);
                                        ThirdNum += rand;
                                    }
                                }
                                break;
                            case "-":
                                if (FirstSectionTotal >= 100)
                                {
                                    int rand = rnd.Next(0, 9);
                                    ThirdNum = rand + FirstSectionTotal;
                                }
                                else 
                                {
                                    ThirdNum = rnd.Next(FirstSectionTotal, 100);
                                }
                                //if (FirstSectionTotal == 0)
                                //{
                                //    FirstNum++;
                                //    FirstSectionTotal++;
                                //}
                                //ThirdNum = GetDigit(FirstSectionTotal, forceState);
                                {
                                    int firstl = Convert.ToInt32(ThirdNum.ToString().Substring(ThirdNum.ToString().Length - 1, 1));
                                    int secondl = Convert.ToInt32(FirstSectionTotal.ToString().Substring(FirstSectionTotal.ToString().Length - 1, 1));
                                    int mindiff = firstl - secondl;
                                    if (mindiff > 0 && mindiff < 9 && rnd.Next(0, 99) < Rate)
                                    {
                                        int rand = rnd.Next((mindiff + 1), 9);
                                        ThirdNum += rand;
                                        if (FirstSectionTotal < 90 && ((ThirdNum  - FirstSectionTotal) < 0))
                                            ThirdNum += 10;
                                        else if ((ThirdNum - FirstSectionTotal) < 0)
                                            FirstNum -= 10;
                                    }
                                }
                                break;
                        }
                        if (!string.IsNullOrEmpty(nextMethod))
                        {
                            Multi = $"{ThirdNum} {nextMethod}";
                        }
                    }
                    else
                    {
                        switch (nextMethod)
                        {
                            case "+":
                                ThirdNum = GetDigit(0, forceState);
                                {
                                    int firstl = Convert.ToInt32(FirstSectionTotal.ToString().Substring(FirstSectionTotal.ToString().Length - 1, 1));
                                    int secondl = Convert.ToInt32(ThirdNum.ToString().Substring(ThirdNum.ToString().Length - 1, 1));
                                    int mindiff = 10 - firstl - secondl;
                                    if (mindiff > 0 && mindiff < 9 && rnd.Next(0, 99) < Rate)
                                    {
                                        int rand = rnd.Next((mindiff + 1), 9);
                                        ThirdNum += rand;
                                    }
                                }
                                break;
                            case "-":
                                if (FirstSectionTotal == 0)
                                {
                                    FirstNum++;
                                    FirstSectionTotal++;
                                }
                                ThirdNum = GetDigit(FirstSectionTotal, forceState);
                                {
                                    int firstl = Convert.ToInt32(FirstSectionTotal.ToString().Substring(FirstSectionTotal.ToString().Length - 1, 1));
                                    int secondl = Convert.ToInt32(ThirdNum.ToString().Substring(ThirdNum.ToString().Length - 1, 1));
                                    int mindiff = firstl - secondl;
                                    if (mindiff > 0 && mindiff < 9 && rnd.Next(0, 99) < Rate)
                                    {
                                        int rand = rnd.Next((mindiff + 1), 9);
                                        ThirdNum += rand;
                                        if (FirstSectionTotal < 90 && ((FirstSectionTotal - ThirdNum) < 0))
                                            FirstNum += 10;
                                        else if ((FirstSectionTotal - ThirdNum) < 0)
                                            ThirdNum -= 10;
                                    }
                                }
                                break;
                        }
                        if (!string.IsNullOrEmpty(nextMethod))
                        {
                            Multi = $"{nextMethod} {ThirdNum}";
                        }
                    }
                }

                if (QuotePoints < QuoteChance)
                    Question = $" {Multi} ({FirstNum} {method} {SecondNum}) = ";
                else
                    Question = $" {FirstNum} {method} {SecondNum} {Multi} = ";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ":" + ex.StackTrace);
            }
            return Question;
        }
    }
}